﻿using System;
using System.Runtime.InteropServices;

namespace MediaRemoteServer
{
    public class MediaList : IDisposable
    {
        #region libvlc functions

        [DllImport("libvlc")]
        private static extern IntPtr libvlc_media_list_new(IntPtr libvlc_instance, IntPtr exception);

        [DllImport("libvlc")]
        private static extern void libvlc_media_list_release(IntPtr p_ml);

        [DllImport("libvlc")]
        private static extern void libvlc_media_list_set_media(IntPtr p_ml, IntPtr p_m, IntPtr p_e);

        [DllImport("libvlc")]
        private static extern IntPtr libvlc_media_list_media(IntPtr p_ml, IntPtr p_e);

        [DllImport("libvlc")]
        private static extern void libvlc_media_list_add_media(IntPtr p_ml, IntPtr p_m, IntPtr p_e);

        [DllImport("libvlc")]
        private static extern void libvlc_media_list_insert_media(IntPtr p_ml, IntPtr p_m, int index, IntPtr p_e);

        [DllImport("libvlc")]
        private static extern void libvlc_media_list_remove_index(IntPtr p_ml, int index, IntPtr p_e);

        [DllImport("libvlc")]
        private static extern int libvlc_media_list_count(IntPtr p_ml, IntPtr p_e);

        [DllImport("libvlc")]
        private static extern IntPtr libvlc_media_list_item_at_index(IntPtr p_ml, int index, IntPtr p_e);

        [DllImport("libvlc")]
        private static extern int libvlc_media_list_index_of_item(IntPtr p_ml, IntPtr p_m, IntPtr p_e);

        [DllImport("libvlc")]
        private static extern int libvlc_media_list_is_readonly(IntPtr p_ml);

        [DllImport("libvlc")]
        private static extern void libvlc_media_list_lock(IntPtr p_ml);

        [DllImport("libvlc")]
        private static extern void libvlc_media_list_unlock(IntPtr p_ml);

        #endregion

        public IntPtr instance { get; private set; }
        private LibVLC libVLC;

        public MediaList(LibVLC libVLCInstance)
        {
            libVLC = libVLCInstance;

            libVLC.clearException();
            instance = libvlc_media_list_new(libVLC.instance, libVLC.pException);
        }

        public void setMedia(MediaItem item)
        {
            libVLC.clearException();
            libvlc_media_list_set_media(instance, item.instance, libVLC.pException);
        }

        public MediaItem getMedia()
        {
            libVLC.clearException();
            IntPtr mediaInstance = libvlc_media_list_media(instance, libVLC.pException);
            return new MediaItem(mediaInstance, libVLC);
        }

        public void addMedia(MediaItem item)
        {
            libVLC.clearException();
            libvlc_media_list_lock(instance);
            libvlc_media_list_add_media(instance, item.instance, libVLC.pException);
            libvlc_media_list_unlock(instance);
        }

        public void insertMedia(MediaItem item, int index)
        {
            libVLC.clearException();
            libvlc_media_list_lock(instance);
            libvlc_media_list_insert_media(instance, item.instance, index, libVLC.pException);
            libvlc_media_list_unlock(instance);
        }

        public void removeIndex(int index)
        {
            libVLC.clearException();
            libvlc_media_list_lock(instance);
            libvlc_media_list_remove_index(instance, index, libVLC.pException);
            libvlc_media_list_unlock(instance);
        }

        public int count()
        {
            libVLC.clearException();
            libvlc_media_list_lock(instance);
            int count = libvlc_media_list_count(instance, libVLC.pException);
            libvlc_media_list_unlock(instance);
            return count;
        }

        public MediaItem itemAtIndex(int index)
        {
            libVLC.clearException();
            libvlc_media_list_lock(instance);
            IntPtr mediaInstance = libvlc_media_list_item_at_index(instance, index, libVLC.pException);
            libvlc_media_list_unlock(instance);
            return new MediaItem(mediaInstance, libVLC);
        }

        public int indexOfItem(MediaItem item)
        {
            libVLC.clearException();
            int index = libvlc_media_list_index_of_item(instance, item.instance, libVLC.pException);
            return index;
        }

        public bool isReadonly()
        {
            libVLC.clearException();
            int result = libvlc_media_list_is_readonly(instance);
            return result != 0;
        }

        #region IDisposable Members

        public void Dispose()
        {
            libvlc_media_list_release(instance);
        }

        #endregion
    }
}
